package org.melanesia.beans;

import java.lang.reflect.Field;
import java.util.Map;

import org.melanesia.beans.exceptions.PropertyAccessException;

/**
 * Property setter using field access.
 *
 * @author marcin.kielar
 */
class FieldSetter implements Setter {

    /** Reflection field for accessing the property. */
    private final Field field;

    /**
     * Constructs new <code>FielsSetter</code> with field accessing the
     * property.
     *
     * @param field
     *            field accessing the property
     */
    FieldSetter(final Field field) {
        this.field = field;
    }

    @Override
    public void set(final Object bean, final Object value, final Map<String, Class<?>> intermediateBeanClasses) {

        try {

            Object acceptedValue = BeanUtils.cast(value, getAcceptedType());
            field.set(bean, acceptedValue);

        } catch (Throwable t) {
            throw new PropertyAccessException("Error mapping bean \"" + bean.getClass() + "\". Cannot set value of field \""
                    + field.getName() + "\" of class \"" + getAcceptedType() + "\" to \"" + value + "\" of class \""
                    + (value == null ? "unknown" : value.getClass()) + "\".", t);
        }
    }

    @Override
    public Class<?> getAcceptedType() {
        return field.getType();
    }
}
